package com.blog4j.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blog4j.common.constants.CommonConstant;
import com.blog4j.common.enums.ErrorEnum;
import com.blog4j.common.enums.MessageStatusEnum;
import com.blog4j.common.exception.Blog4jException;
import com.blog4j.user.entity.MessageEntity;
import com.blog4j.user.mapper.MessageMapper;
import com.blog4j.user.mapper.UserMapper;
import com.blog4j.user.service.MessageService;
import com.blog4j.user.vo.req.DelMessageReqVo;
import com.blog4j.user.vo.req.MessageListReqVo;
import com.blog4j.user.vo.resp.MessageRespVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author 98k灬
 * @version v1.0.0
 * @Description : 功能描述
 * @Create on : 2024/8/15 12:15
 **/
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class MessageServiceImpl extends ServiceImpl<MessageMapper, MessageEntity>
        implements MessageService {
    private final UserMapper userMapper;

    /**
     * 检查用户是否有新消息
     *
     * @param userId 用户ID
     * @return 新消息数量
     */
    @Override
    public Integer userHasNewMessage(String userId) {
        LambdaQueryWrapper<MessageEntity> wrapper = new LambdaQueryWrapper<MessageEntity>()
                .eq(MessageEntity::getToUserId, userId)
                .eq(MessageEntity::getMessageStatus, MessageStatusEnum.UNREAD.getCode());
        return this.baseMapper.selectCount(wrapper);
    }

    /**
     * 获取消息列表
     *
     * @param reqVo 请求信息
     * @return 消息列表
     */
    @Override
    public PageInfo<MessageRespVo> messageList(MessageListReqVo reqVo) {
        Integer pageNo;
        pageNo = reqVo.getPageNo();
        Integer pageSize = reqVo.getPageSize();
        if (pageSize > CommonConstant.MAX_PAGE_SIZE) {
            pageSize = CommonConstant.MAX_PAGE_SIZE;
        }
        String userId = StpUtil.getLoginIdAsString();
        Optional.ofNullable(userMapper.selectById(userId))
                .orElseThrow(() -> new Blog4jException(ErrorEnum.USER_NOT_EXIST_ERROR));
        PageHelper.startPage(pageNo, pageSize);
        List<MessageRespVo> messageList = this.baseMapper.getMessageList(userId);
        if (CollectionUtil.isEmpty(messageList)) {
            return new PageInfo<>(new ArrayList<>());
        }
        return new PageInfo<>(messageList);
    }

    /**
     * 删除消息
     *
     * @param reqVo 请求信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteMessage(DelMessageReqVo reqVo) {
        List<Long> ids = reqVo.getIds();
        this.baseMapper.deleteBatchIds(ids);
    }

    /**
     * 全部已读消息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void allReadMessage() {
        String userId = StpUtil.getLoginIdAsString();
        Optional.ofNullable(userMapper.selectById(userId))
                .orElseThrow(() -> new Blog4jException(ErrorEnum.USER_NOT_EXIST_ERROR));
        LambdaQueryWrapper<MessageEntity> wrapper = new LambdaQueryWrapper<MessageEntity>()
                .eq(MessageEntity::getToUserId, userId)
                .eq(MessageEntity::getMessageStatus, MessageStatusEnum.UNREAD.getCode());
        List<MessageEntity> list = this.baseMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(list)) {
            return;
        }

        for (MessageEntity message : list) {
            message.setMessageStatus(MessageStatusEnum.READ.getCode());
        }
        this.updateBatchById(list);
    }

    /**
     * 删除全部消息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteAllMessage() {
        String userId = StpUtil.getLoginIdAsString();
        Optional.ofNullable(userMapper.selectById(userId))
                .orElseThrow(() -> new Blog4jException(ErrorEnum.USER_NOT_EXIST_ERROR));
        LambdaQueryWrapper<MessageEntity> wrapper = new LambdaQueryWrapper<MessageEntity>()
                .eq(MessageEntity::getToUserId, userId);
        List<MessageEntity> list = this.baseMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        Set<Long> ids = list.stream().map(MessageEntity::getId).collect(Collectors.toSet());
        this.baseMapper.deleteBatchIds(ids);
    }
}
